package com.example.demo.service.impl;

import com.example.demo.entity.Consultant;
import com.example.demo.entity.Supervisor;
import com.example.demo.entity.relation.SupervisorBind;
import com.example.demo.exception.EntityAlreadyExistException;
import com.example.demo.exception.EntityNotExistException;
import com.example.demo.repository.dao.ConsultantDao;
import com.example.demo.repository.dao.SupervisorDao;
import com.example.demo.repository.dao.relation.SupervisorBindDao;
import com.example.demo.service.SupervisorService;
import com.example.demo.utils.JPAUpdateUtil;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class SupervisorServiceImpl implements SupervisorService {
    private final SupervisorDao supervisorDao;
    private final SupervisorBindDao supervisorBindDao;
    private final ConsultantDao consultantDao;

    public SupervisorServiceImpl(SupervisorDao supervisorDao,
                                 SupervisorBindDao supervisorBindDao,
                                 ConsultantDao consultantDao){
        this.supervisorDao = supervisorDao;
        this.supervisorBindDao = supervisorBindDao;
        this.consultantDao = consultantDao;
    }

    @Override
    public boolean existSupervisor(String id) {
        if (id == null) {
            return false;
        }

        return supervisorDao.existsById(id);
    }

    @Override
    public String addSupervisor(Supervisor supervisor) throws EntityAlreadyExistException {
        String supervisorId = supervisor.getId();
        Optional<Supervisor> origin = supervisorDao.findById(supervisorId);
        if (origin.isPresent()) {
            throw new EntityAlreadyExistException("id 为 " + supervisorId + " 的督导已经存在");
        } else {
            supervisorDao.save(supervisor);
        }

        return supervisor.getId();
    }

    @Override
    public void deleteSupervisor(String id) {
        if (supervisorDao.existsById(id)) {
            supervisorDao.deleteById(id);
        }
    }

    @Override
    public void deleteSupervisors(List<String> ids) {
        for (String id : ids) {
            deleteSupervisor(id);
        }
    }

    @Override
    public void updateSupervisor(String id, Supervisor supervisor) throws EntityNotExistException {
        Optional<Supervisor> origin = supervisorDao.findById(id);
        if (origin.isPresent()) {
            Supervisor old = origin.get();
            JPAUpdateUtil.copyNullProperties(supervisor, old);
            supervisorDao.save(old);
        } else {
            throw new EntityNotExistException("id 为 " + id + " 的 supervisor不存在");
        }
    }

    @Override
    public Supervisor getSupervisor(String id) throws EntityNotExistException {
        Optional<Supervisor> origin = supervisorDao.findById(id);
        if (origin.isPresent()) {
            return origin.get();
        } else {
            throw new EntityNotExistException("id 为 " + id + " 的 supervisor不存在");
        }
    }

    @Override
    public List<Consultant> getBoundConsultants(String supervisorId) {
        List<SupervisorBind> allSupervisorBind = supervisorBindDao.findAllBySupervisorId(supervisorId);
        List<String> boundConsultantIds = new ArrayList<>();

        for (SupervisorBind supervisorBind : allSupervisorBind) {
            boundConsultantIds.add(supervisorBind.getConsultantId());
        }

        return consultantDao.findAllById(boundConsultantIds);
    }

    @Override
    public List<Supervisor> getSupervisors(List<String> ids) {
        if (ids != null) {
            return supervisorDao.findAllById(ids);
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public List<Supervisor> getAllSupervisor() {
        return supervisorDao.findAll();
    }

    @Override
    public Supervisor getSupervisorByConsultantId(String id) throws EntityNotExistException {
        Supervisor supervisor = supervisorDao.findByConsultantId(id);
        if(supervisor==null) throw new EntityNotExistException("督导不存在");
        return supervisor;
    }
}
